package com.naiterui.ehp.bs.b2c.cart.controller;

import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bs.b2c.cart.exception.CartExceptionCodes;
import com.naiterui.ehp.bs.b2c.cart.service.ICartService;
import com.naiterui.ehp.bs.b2c.cart.vo.CartVO;
import com.naiterui.ehp.bs.b2c.cart.vo.SettlementVO;
import com.naiterui.ehp.bs.b2c.cart.vo.param.CartUpdateItemParamVO;
import com.naiterui.ehp.bs.b2c.common.util.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

/**
 * @author guoyongxiang
 * @date 2019-05-13 13:50
 * @since 1.0.0
 */
@Validated
@Api(tags = SwaggerTag.PATIENT + SwaggerTag.CART)
@RequestMapping("b2c/carts")
@RestController
public class CartController {

    private static final Logger LOGGER = LoggerFactory.getLogger(CartController.class);

    @Autowired
    private ICartService cartService;

    /**
     * 获取购物车
     *
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "获取购物车列表")
    @GetMapping("info")
    public ResponseVO<CartVO> info() throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();
        CartVO cartVO = cartService.getInfo(userId);
        return PublicService.returnResponseVO(cartVO);
    }

    /**
     * 添加购物车
     *
     * @param recomId
     * @param skuId
     * @param quantity
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "添加购物车", notes = "recomId 与 skuId 不可同时为空")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "recomId", value = "处方ID(默认0)", required = true, paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "skuId", value = "商品skuId(处方ID为0时必传)", paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "quantity", value = "新增商品数量(skuId不为空时有效)", required = true, paramType = "query", dataType = "long")
    })
    @PostMapping("add")
    public ResponseVO<CartVO> add(Long recomId, Long skuId, Integer quantity) throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();
        if (skuId != null) {
            if (quantity == null || quantity < 1) {
                LOGGER.warn("添加购物车失败-添加商品需设置商品数量 userId:{}, skuId:{}, quantity:{}", userId, skuId, quantity);
                throw new BusinessException(CartExceptionCodes.PARAM_ERROR);
            }
        }
        if ((recomId == null || recomId == 0) && (skuId == null || skuId == 0)) {
            LOGGER.warn("添加购物车失败-添加商品需设置商品数量 userId:{}, skuId:{}, quantity:{}", userId, skuId, quantity);
            throw new BusinessException(CartExceptionCodes.PARAM_ERROR, "参数异常,处方ID或商品ID缺失");
        }
        cartService.add(userId, recomId, skuId, quantity);
        // CartVO cartVO = cartService.getInfo(userId);
        CartVO cartVO = null;
        return PublicService.returnResponseVO(cartVO);
    }

    /**
     * 修改购物车勾选
     *
     * @param all
     * @param recomId
     * @param itemId
     * @param selected
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "修改购物车勾选", notes = "处方不支持单商品勾选（非全选状态all始终为0）")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "all", value = "全选(0:未全选, 1:全选)", required = true, paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "recomId", value = "处方ID(默认0)", required = true, paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "itemId", value = "购物车商品项ID(处方ID为0时必传)", paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "selected", value = "勾选状态(0:未选中, 1:选中)", required = true, paramType = "query", dataType = "long")
    })
    @PostMapping("update/selected")
    public ResponseVO<CartVO> updateSelected(@NotNull @Min(0) @Max(1) Integer all, @NotNull @Min(0) Long recomId, Long itemId,
        @NotNull @Min(0) @Max(1) Integer selected) throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();
        if (recomId == 0 && itemId == null) {
            LOGGER.warn("修改购物车失败-处方ID和itemId不可同时为空 userId:{}, all:{}, recomId:{}, itemId:{}, selected:{}", userId, all, recomId, itemId, selected);
            throw new BusinessException(CartExceptionCodes.PARAM_ERROR);
        }

        cartService.updateSelected(userId, all, recomId, itemId, selected);
        CartVO cartVO = cartService.getInfo(userId);
        return PublicService.returnResponseVO(cartVO);
    }

    /**
     * 修改购物车商品数量
     *
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "修改购物车商品数量", notes = "处方商品不支持修改数量")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "itemId", value = "购物车商品项ID(处方ID为0时必传)", paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "quantity", value = "新增商品数量(skuId不为空时有效)", required = true, paramType = "query", dataType = "long")
    })
    @PostMapping("update/quantity")
    public ResponseVO<CartVO> updateQuantity(CartUpdateItemParamVO paramVO) throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();

        cartService.updateQuantity(userId, paramVO.getItemId(), paramVO.getQuantity());
        CartVO cartVO = cartService.getInfo(userId);
        return PublicService.returnResponseVO(cartVO);
    }

    /**
     * 删除购物车商品
     *
     * @param recomId
     * @param itemId
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "删除购物车商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "recomId", value = "处方ID(默认0)", required = true, paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "itemId", value = "购物车商品项ID(处方ID为0时必传)", paramType = "query", dataType = "long"),
    })
    @PostMapping("delete")
    public ResponseVO<CartVO> delete(@NotNull Long recomId, Long itemId) throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();
        if (recomId == 0 && itemId == null) {
            LOGGER.warn("删除购物车失败-处方ID和itemId不可同时为空 userId:{}, recomId:{}, itemId:{}", userId, recomId, itemId);
            throw new BusinessException(CartExceptionCodes.PARAM_ERROR);
        }

        cartService.delete(userId, recomId, itemId);
        CartVO cartVO = cartService.getInfo(userId);
        return PublicService.returnResponseVO(cartVO);
    }

    /**
     * 结算中心
     *
     * @return
     */
    @ApiOperation(value = "结算中心")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "shippingInfoId", value = "收货地址ID(不传返回默认地址)", paramType = "query", dataType = "long"),
    })
    @GetMapping("settlements")
    public ResponseVO<SettlementVO> settlements(Long shippingInfoId) throws BusinessException {
        Long userId = UserUtils.getUser().getPatientId();
        SettlementVO settlementVO = cartService.settlements(userId, shippingInfoId);
        return PublicService.returnResponseVO(settlementVO);
    }

    @ApiOperation(value = "处方直接购买结算")
    @GetMapping("/recom/settlements")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "recomId", value = "处方ID", paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "userId", value = "用户ID", paramType = "query", dataType = "long"),
        @ApiImplicitParam(name = "shippingInfoId", value = "收货地址ID", paramType = "query", dataType = "long")
    })
    public ResponseVO<SettlementVO> recomSettlement(Long userId, Long recomId, Long shippingInfoId) throws BusinessException {
        LOGGER.info("处方直接结算， userId {}, recomId {}, shippingInfoId{}", userId, recomId, shippingInfoId);
        return PublicService.returnResponseVO(cartService.recomSettlement(userId, recomId, shippingInfoId));
    }
}
